/**
 * Copyright 2012 ibiblio
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.ibiblio.terasaur.item

import org.ibiblio.terasaur.bt.Torrent
import org.ibiblio.terasaur.item.Item
import org.grails.plugins.lookups.Lookup
import org.grails.plugins.lookups.LookupValue
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
import org.ibiblio.terasaur.controller.ParamsHelper
import grails.plugins.springsecurity.Secured
import org.apache.solr.client.solrj.SolrQuery

class BrowseController {
    def browseService // injected
    def searchService // injected
    def springSecurityService // injected
    static ParamsHelper _paramsHelper = new ParamsHelper()

    def index = {
        redirect(controller:"browse", action: "recent")
    }

    def category = {
        def typeCode = null
        if (params.id) {
            typeCode = _getTypeCode(params.id)
        }
        if (!typeCode) {
            redirect(controller:"browse", action: "recent")
            return
        }

        def searchParams = _getCategorySearchParams(typeCode)
        def result = searchService.query(searchParams)

        def label = message(code:'item.browse.category.label', args:[params.id])
        def map = [
            pageTitle: label,
            listLabel: label,
            itemListType: 'solr',
            paginationParams: [id:params.id],
            showItemType: false,
            error: (result.error) ? true : false,
        ]

        _setItemListElementsForSearchResult(map, result)
        _setFlashMessageForSearchResult(result)
        render(view:"/item/list", model:map)
    }


    def popular = {
        def listParams = _paramsHelper.getOffsetMax(params)
        Map results = browseService.popular(listParams)
        def label = message(code:'item.browse.popular.label')
        def map = [
            pageTitle: "ibiblio terasaur: " + label,
            listLabel: label,
            itemList: results['results'],
            itemListTotal: results['totalCount'],
            showResultsTotal: false,
            error: false
        ]
        render(view:"/item/list", model:map)
    }

    def recent = {
        Map searchParams = _paramsHelper.getOffsetMax(params)
        searchParams.sort = [[field:'date_created', order:SolrQuery.ORDER.desc]]
        searchParams.rawQuery = '*:*'
        Map result = searchService.query(searchParams)

        def label = message(code:'item.browse.recent.label')
        def map = [
            pageTitle: "ibiblio terasaur: " + label,
            listLabel: label,
            itemListType: 'solr',
            showResultsTotal: false,
            error: (result.error) ? true : false
        ]
        _setItemListElementsForSearchResult(map, result)
        _setFlashMessageForSearchResult(result)
        render(view:"/item/list", model:map)
    }

    @Secured(['IS_AUTHENTICATED_REMEMBERED'])
    def my_items = {
        def listParams = _paramsHelper.getOffsetMax(params)
        if (params.show_deleted && params.show_deleted == '1') {
            listParams.showDeleted = true
        } else {
            listParams.showDeleted = false
        }
        Map results = browseService.myItems(listParams, springSecurityService.currentUser)
        def label = message(code:'item.browse.my_items.label')
        def map = [
            pageTitle: "ibiblio terasaur: " + label,
            listLabel: label,
            itemList: results['results'],
            itemListTotal: results['totalCount'],
            error: false
        ]
        render(view:"/item/list", model:map)
    }

    /**
     * Helpers
     */
    private Map _getCategorySearchParams(Integer type) {
        Map searchParams = _paramsHelper.getOffsetMax(params)
        searchParams.rawQuery = '*:*'
        searchParams.filters = ['type:' + type]
        return searchParams
    }

    private void _setFlashMessageForSearchResult(result) {
        if (result.error) {
            flash.message = message(code:result.error)
        }
    }

    private void _setItemListElementsForSearchResult(Map map, result) {
        if (result.itemList) {
            map.itemList = result.itemList
            map.itemListTotal = result.documentList.numFound
        } else {
            map.itemList = []
            map.itemListTotal = 0
        }
    }

    private int _getTypeCode(String value) {
        // TODO: there must be a more efficient way to do this
        // Try using LookupValue.createCriteria()
        List lst = Lookup.codeList("item.type")
        int code = 0
        for (int idx = 0; idx < lst.size; ++idx) {
            if (value.equals(lst[idx].value.toLowerCase())) {
                code = lst[idx].code
                break
            }
        }
        return code
    }
}
